import { defineStore } from "pinia";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import { getColors } from "@/utils";

import { getStocks, getPrices } from "@/api";

export const useAppStore = defineStore("app", {
	state: () => ({
		time: dayjs(),
		stocks: getStocks(),
		prices: getPrices(),
		current: dayjs().format("YYYY-MM-DD"),
		historyVisible: false,
		historyRecord: null,
		colors: getColors(),
	}),
	getters: {
		getCurrentTime: (state) => {
			// console.log(state.time)
			return {
				time: dayjs(state.time).format("HH:mm:ss") ?? "",
				date: dayjs(state.time).format("YYYY-MM-DD") ?? "",
				weekday: dayjs(state.time).locale("zh-cn").format("dddd") ?? "",
			};
		},
		getFullStocks: (state) => {
			return state.stocks
				.filter((stock) => stock.disabled === false)
				.map((stock) => ({
					...stock,
					prices: state.prices.map((price) => {
						const cur = price.prices.find(
							(data) => data.code === stock.code
						);

						return {
							time: price.time,
							price: cur?.price ?? 0,
							costs: cur?.costs ?? [0, 0],
							shares: cur?.shares ?? [0, 0],
						};
					}),
				}));
		},
		getLatestStocks: (state) => {
			return state.getFullStocks.map((stock) => {
				const currentPrice = stock.prices.find(
					(p) => p.time === state.current
				);

				const allShare = currentPrice
					? currentPrice.shares.reduce((prev, cur) => prev + cur, 0)
					: 0;
				const allCost = currentPrice
					? currentPrice.costs.reduce(
							(prev, cur, index) =>
								prev + cur * currentPrice.shares[index],
							0
					  )
					: 0;
				const cost = allShare ? allCost / allShare : 0;

				const summary = currentPrice
					? currentPrice.shares.reduce((prev, cur) => prev + cur, 0) *
					  currentPrice.price
					: 0;

				const profit = allCost ? (summary / allCost - 1) * 100 : 0;

				return {
					key: stock.id,
					id: stock.id,
					name: stock.name,
					code: stock.code,
					industry: stock.industry,
					time: currentPrice?.time ?? state.current,
					price: currentPrice?.price ?? 0,
					share_l: currentPrice?.shares[0] ?? 0,
					share_c: currentPrice?.shares[1] ?? 0,
					cost_l: currentPrice?.costs[0] ?? 0,
					cost_c: currentPrice?.costs[1] ?? 0,
					allCost,
					allShare,
					cost,
					summary,
					profit,
					show: stock.show,
				};
			});
		},
		getLatestStocksByIndustry: (state) => {
			const groupBy = (objectArray, property) => {
				return objectArray.reduce((acc, obj) => {
					const key = obj[property];
					const curGroup = acc[key] ?? [];

					return { ...acc, [key]: [...curGroup, obj] };
				}, {});
			};

			const fromGroup = (object) => {
				return Object.entries(object).map(([key, values]) => ({
					name: key,
					value: values.reduce((prev, cur) => prev + cur.summary, 0),
				}));
			};

			return fromGroup(groupBy(state.getLatestStocks, "industry"));
		},
		getCurrent: (state) => state.current,
		getStockTend: (state) => {
			if (state.historyRecord) {
				return state.getFullStocks
					.find((stock) => stock.code === state.historyRecord.code)
					.prices.sort((a, b) => {
						if (dayjs(a.time).isBefore(dayjs(b.time))) {
							return -1;
						}

						if (dayjs(a.time).isAfter(dayjs(b.time))) {
							return 1;
						}

						return 0;
					})
					.map((stock) => {
						const allShare = stock.shares.reduce(
							(prev, cur) => prev + cur,
							0
						);
						const allCost = stock.costs.reduce(
							(prev, cur, index) =>
								prev + cur * stock.shares[index],
							0
						);
						const cost = allShare ? allCost / allShare : 0;
						const summary = allShare * stock.price;
						const profit = allCost
							? (summary / allCost - 1) * 100
							: 0;

						return {
							...stock,
							allCost,
							allShare,
							cost,
							summary,
							profit,
						};
					});
			}

			return [];
		},
		getChartLatestStocks: (state) => {
			return state.getFullStocks
				.filter((s) => s.show)
				.map((stock) => {
					const currentPrice = stock.prices.find(
						(p) => p.time === state.current
					);

					const allShare = currentPrice
						? currentPrice.shares.reduce(
								(prev, cur) => prev + cur,
								0
						  )
						: 0;
					const allCost = currentPrice
						? currentPrice.costs.reduce(
								(prev, cur, index) =>
									prev + cur * currentPrice.shares[index],
								0
						  )
						: 0;
					const cost = allShare ? allCost / allShare : 0;

					const summary = currentPrice
						? currentPrice.shares.reduce(
								(prev, cur) => prev + cur,
								0
						  ) * currentPrice.price
						: 0;

					const profit = allCost ? (summary / allCost - 1) * 100 : 0;

					return {
						key: stock.id,
						id: stock.id,
						name: stock.name,
						code: stock.code,
						industry: stock.industry,
						time: currentPrice?.time ?? state.current,
						price: currentPrice?.price ?? 0,
						share_l: currentPrice?.shares[0] ?? 0,
						share_c: currentPrice?.shares[1] ?? 0,
						cost_l: currentPrice?.costs[0] ?? 0,
						cost_c: currentPrice?.costs[1] ?? 0,
						allCost,
						allShare,
						cost,
						summary,
						profit,
						show: stock.show,
					};
				});
		},
		getChartLatestStocksByIndustry: (state) => {
			const groupBy = (objectArray, property) => {
				return objectArray.reduce((acc, obj) => {
					const key = obj[property];
					const curGroup = acc[key] ?? [];

					return { ...acc, [key]: [...curGroup, obj] };
				}, {});
			};

			const fromGroup = (object) => {
				return Object.entries(object).map(([key, values]) => ({
					name: key,
					value: values.reduce((prev, cur) => prev + cur.summary, 0),
				}));
			};

			return fromGroup(groupBy(state.getChartLatestStocks, "industry"));
		},
	},
	actions: {
		updateState(partial) {
			this.$patch(partial);
		},
		updateStock(partial) {
			const stock = this.stocks.find((s) => s.id === partial.id);
			const newStocks = this.stocks.map((s) =>
				s.id === partial.id ? Object.assign({}, stock, partial) : s
			);

			this.updateState({ stocks: newStocks });
		},
	},
	persist: {
		// storage: localStorage,
		paths: [
			"stocks",
			"current",
			"historyVisible",
			"historyRecord",
			"colors",
		],
	},
	// persist: false,
});
